package com.yupi.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yupi.springbootinit.mapper.DepartmentMapper;
import com.yupi.springbootinit.mapper.WorkflowTaskMapper;
import com.yupi.springbootinit.model.entity.Department;
import com.yupi.springbootinit.model.entity.WorkflowTask;
import com.yupi.springbootinit.service.ProductionStatisticsService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 生产统计服务实现
 */
@Slf4j
@Service
public class ProductionStatisticsServiceImpl implements ProductionStatisticsService {

    // ==================== 常量定义 ====================
    private static final String PRODUCTION_DEPT_CODE = "SC001";
    private static final String STATUS_PENDING = "PENDING";
    private static final String STATUS_IN_PROGRESS = "IN_PROGRESS";
    private static final String STATUS_DONE = "DONE";

    // ==================== 依赖注入 ====================
    @Resource
    private WorkflowTaskMapper workflowTaskMapper;
    @Resource
    private DepartmentMapper departmentMapper;

    // ==================== 接口实现 ====================

    @Override
    public Map<String, Long> getTaskStatistics(Long userId) {
        Map<String, Long> statistics = new HashMap<>();
        Long prodDeptId = getProductionDeptId();
        if (prodDeptId == null) {
            return statistics;
        }

        LocalDateTime now = LocalDateTime.now();

        // 统计各状态
        String[] statuses = {STATUS_PENDING, STATUS_IN_PROGRESS, STATUS_DONE};
        for (String s : statuses) {
            LambdaQueryWrapper<WorkflowTask> qw = new LambdaQueryWrapper<>();
            qw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                    .eq(WorkflowTask::getTaskStatus, s)
                    .eq(WorkflowTask::getIsDelete, 0);
            if (userId != null) {
                qw.eq(WorkflowTask::getClaimedBy, userId);
            }
            Long count = workflowTaskMapper.selectCount(qw);
            statistics.put(s, count != null ? count : 0L);
        }

        // 逾期任务统计
        LambdaQueryWrapper<WorkflowTask> overdueQw = new LambdaQueryWrapper<>();
        overdueQw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .ne(WorkflowTask::getTaskStatus, STATUS_DONE)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            overdueQw.eq(WorkflowTask::getClaimedBy, userId);
        }
        Long overdueCount = workflowTaskMapper.selectCount(overdueQw);
        statistics.put("OVERTIME", overdueCount != null ? overdueCount : 0L);

        // 细分逾期统计
        LambdaQueryWrapper<WorkflowTask> overduePendingQw = new LambdaQueryWrapper<>();
        overduePendingQw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .eq(WorkflowTask::getTaskStatus, STATUS_PENDING)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            overduePendingQw.eq(WorkflowTask::getClaimedBy, userId);
        }
        Long overduePending = workflowTaskMapper.selectCount(overduePendingQw);
        statistics.put("PENDING_OVERDUE", overduePending != null ? overduePending : 0L);

        LambdaQueryWrapper<WorkflowTask> overdueInProgressQw = new LambdaQueryWrapper<>();
        overdueInProgressQw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .eq(WorkflowTask::getTaskStatus, STATUS_IN_PROGRESS)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            overdueInProgressQw.eq(WorkflowTask::getClaimedBy, userId);
        }
        Long overdueInProgress = workflowTaskMapper.selectCount(overdueInProgressQw);
        statistics.put("IN_PROGRESS_OVERDUE", overdueInProgress != null ? overdueInProgress : 0L);

        log.debug("任务统计完成 - userId={}, PENDING={}, IN_PROGRESS={}, DONE={}, OVERTIME={}",
                userId, statistics.get(STATUS_PENDING), statistics.get(STATUS_IN_PROGRESS),
                statistics.get(STATUS_DONE), statistics.get("OVERTIME"));

        return statistics;
    }

    @Override
    public Map<String, Long> getCleaningTaskStatistics(Long userId) {
        return getTaskStatisticsByType(userId, "PRODUCTION_PREP_CLEANING");
    }

    @Override
    public Map<String, Long> getProductionTaskStatistics(Long userId) {
        Map<String, Long> statistics = new HashMap<>();
        Long prodDeptId = getProductionDeptId();
        if (prodDeptId == null) {
            return statistics;
        }

        LocalDateTime now = LocalDateTime.now();

        // 统计各状态任务数（只统计烘粉清机任务已完成的生产任务）
        String[] statuses = {STATUS_PENDING, STATUS_IN_PROGRESS, STATUS_DONE};
        for (String s : statuses) {
            LambdaQueryWrapper<WorkflowTask> qw = new LambdaQueryWrapper<>();
            qw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                    .eq(WorkflowTask::getTaskType, "PRODUCTION_WORKORDER")
                    .eq(WorkflowTask::getTaskStatus, s)
                    .eq(WorkflowTask::getIsDelete, 0);
            if (userId != null) {
                qw.eq(WorkflowTask::getClaimedBy, userId);
            }

            // 只统计烘粉清机任务已完成的生产任务
            qw.apply("EXISTS (SELECT 1 FROM workflow_task wt2 " +
                    "WHERE wt2.bizType = 'PROCESS_BATCH' " +
                    "AND wt2.bizId = workflow_task.bizId " +
                    "AND wt2.taskType = 'PRODUCTION_PREP_CLEANING' " +
                    "AND wt2.taskStatus = 'DONE' " +
                    "AND wt2.isDelete = 0)");

            Long count = workflowTaskMapper.selectCount(qw);
            statistics.put(s, count != null ? count : 0L);
        }

        // 逾期任务统计
        LambdaQueryWrapper<WorkflowTask> overdueQw = new LambdaQueryWrapper<>();
        overdueQw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .eq(WorkflowTask::getTaskType, "PRODUCTION_WORKORDER")
                .ne(WorkflowTask::getTaskStatus, STATUS_DONE)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            overdueQw.eq(WorkflowTask::getClaimedBy, userId);
        }

        overdueQw.apply("EXISTS (SELECT 1 FROM workflow_task wt2 " +
                "WHERE wt2.bizType = 'PROCESS_BATCH' " +
                "AND wt2.bizId = workflow_task.bizId " +
                "AND wt2.taskType = 'PRODUCTION_PREP_CLEANING' " +
                "AND wt2.taskStatus = 'DONE' " +
                "AND wt2.isDelete = 0)");

        Long overdueCount = workflowTaskMapper.selectCount(overdueQw);
        statistics.put("OVERTIME", overdueCount != null ? overdueCount : 0L);

        // 细分逾期统计
        statistics.put("PENDING_OVERDUE",
                countOverdueByStatus(userId, prodDeptId, STATUS_PENDING, now));
        statistics.put("IN_PROGRESS_OVERDUE",
                countOverdueByStatus(userId, prodDeptId, STATUS_IN_PROGRESS, now));

        log.debug("生产任务统计 - userId={}, PENDING={}, IN_PROGRESS={}, DONE={}, OVERTIME={}",
                userId, statistics.get(STATUS_PENDING), statistics.get(STATUS_IN_PROGRESS),
                statistics.get(STATUS_DONE), statistics.get("OVERTIME"));

        return statistics;
    }

    // ==================== 私有辅助方法 ====================

    /**
     * 获取生产部门ID
     */
    private Long getProductionDeptId() {
        Department prodDept = departmentMapper.selectOne(
                new LambdaQueryWrapper<Department>()
                        .eq(Department::getDepartmentCode, PRODUCTION_DEPT_CODE)
                        .eq(Department::getIsDelete, 0)
                        .last("LIMIT 1")
        );
        return prodDept != null ? prodDept.getId() : null;
    }

    /**
     * 按任务类型统计（通用方法）
     *
     * @param userId 用户ID
     * @param taskType 任务类型
     * @return 统计结果
     */
    private Map<String, Long> getTaskStatisticsByType(Long userId, String taskType) {
        Map<String, Long> statistics = new HashMap<>();
        Long prodDeptId = getProductionDeptId();
        if (prodDeptId == null) {
            return statistics;
        }

        LocalDateTime now = LocalDateTime.now();

        // 统计各状态
        String[] statuses = {STATUS_PENDING, STATUS_IN_PROGRESS, STATUS_DONE};
        for (String s : statuses) {
            LambdaQueryWrapper<WorkflowTask> qw = new LambdaQueryWrapper<>();
            qw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                    .eq(WorkflowTask::getTaskType, taskType)
                    .eq(WorkflowTask::getTaskStatus, s)
                    .eq(WorkflowTask::getIsDelete, 0);
            if (userId != null) {
                qw.eq(WorkflowTask::getClaimedBy, userId);
            }
            Long count = workflowTaskMapper.selectCount(qw);
            statistics.put(s, count != null ? count : 0L);
        }

        // 逾期任务统计
        LambdaQueryWrapper<WorkflowTask> overdueQw = new LambdaQueryWrapper<>();
        overdueQw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .eq(WorkflowTask::getTaskType, taskType)
                .ne(WorkflowTask::getTaskStatus, STATUS_DONE)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            overdueQw.eq(WorkflowTask::getClaimedBy, userId);
        }
        Long overdueCount = workflowTaskMapper.selectCount(overdueQw);
        statistics.put("OVERTIME", overdueCount != null ? overdueCount : 0L);

        // 细分逾期统计
        LambdaQueryWrapper<WorkflowTask> overduePendingQw = new LambdaQueryWrapper<>();
        overduePendingQw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .eq(WorkflowTask::getTaskType, taskType)
                .eq(WorkflowTask::getTaskStatus, STATUS_PENDING)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            overduePendingQw.eq(WorkflowTask::getClaimedBy, userId);
        }
        Long overduePending = workflowTaskMapper.selectCount(overduePendingQw);
        statistics.put("PENDING_OVERDUE", overduePending != null ? overduePending : 0L);

        LambdaQueryWrapper<WorkflowTask> overdueInProgressQw = new LambdaQueryWrapper<>();
        overdueInProgressQw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .eq(WorkflowTask::getTaskType, taskType)
                .eq(WorkflowTask::getTaskStatus, STATUS_IN_PROGRESS)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            overdueInProgressQw.eq(WorkflowTask::getClaimedBy, userId);
        }
        Long overdueInProgress = workflowTaskMapper.selectCount(overdueInProgressQw);
        statistics.put("IN_PROGRESS_OVERDUE", overdueInProgress != null ? overdueInProgress : 0L);

        log.debug("{}任务统计完成 - userId={}, PENDING={}, IN_PROGRESS={}, DONE={}, OVERTIME={}",
                taskType, userId, statistics.get(STATUS_PENDING), statistics.get(STATUS_IN_PROGRESS),
                statistics.get(STATUS_DONE), statistics.get("OVERTIME"));

        return statistics;
    }

    /**
     * 统计指定状态的逾期任务数（生产任务专用）
     */
    private Long countOverdueByStatus(Long userId, Long prodDeptId, String status, LocalDateTime now) {
        LambdaQueryWrapper<WorkflowTask> qw = new LambdaQueryWrapper<>();
        qw.eq(WorkflowTask::getDepartmentId, prodDeptId)
                .eq(WorkflowTask::getTaskType, "PRODUCTION_WORKORDER")
                .eq(WorkflowTask::getTaskStatus, status)
                .isNotNull(WorkflowTask::getExpectedCompleteTime)
                .lt(WorkflowTask::getExpectedCompleteTime, now)
                .eq(WorkflowTask::getIsDelete, 0);
        if (userId != null) {
            qw.eq(WorkflowTask::getClaimedBy, userId);
        }

        qw.apply("EXISTS (SELECT 1 FROM workflow_task wt2 " +
                "WHERE wt2.bizType = 'PROCESS_BATCH' " +
                "AND wt2.bizId = workflow_task.bizId " +
                "AND wt2.taskType = 'PRODUCTION_PREP_CLEANING' " +
                "AND wt2.taskStatus = 'DONE' " +
                "AND wt2.isDelete = 0)");

        Long count = workflowTaskMapper.selectCount(qw);
        return count != null ? count : 0L;
    }
}